﻿using MemoDb.Tests.Model;
using NUnit.Framework;

namespace MemoDb.Tests
{
    [TestFixture]
    public class InsertTests
    {
        [Test]
        public void ValuesOnly()
        {
            var memo = new Memo()
                            .Map<City>();

            var buenosAires = new City
                                {
                                    Id = 1,
                                    Name = "Buenos Aires"
                                };
            using(var s = memo.CreateSession())
            {
                s.Insert(buenosAires);
                s.Flush();
            }

            City buenosAires2;

            using (var s = memo.CreateSession())
            {
                buenosAires2 = s.GetById<City>(buenosAires.Id);
            }

            Assert.AreNotEqual(buenosAires,buenosAires2);
            Assert.AreEqual(buenosAires.Name, buenosAires2.Name);
        }

        [Test]
        public void ValuesAndReferences()
        {
            var memo = new Memo()
                            .Map<City>()
                            .Map<Country>();
            var argentina = new Country
                                {
                                    Id = 1,
                                    Name = "Argentina"
                                };
            var buenosAires = new City
            {
                Id = 1,
                Name = "Buenos Aires",
                Country = argentina
            };

            using (var s = memo.CreateSession())
            {
                s.Insert(argentina);
                s.Insert(buenosAires);
                s.Flush();
            }

            City buenosAires2;
            Country argentina2;
            using (var s = memo.CreateSession())
            {
                buenosAires2 = s.GetById<City>(buenosAires.Id);
                argentina2 = s.GetById<Country>(argentina.Id);
            }

            Assert.AreNotEqual(argentina, buenosAires2.Country);
            Assert.AreEqual(argentina2, buenosAires2.Country);
        }

        [Test]
        public void ChangesOutsideASessionShouldNotBeStored()
        {
            var memo = new Memo()
                .Map<City>()
                .Map<Country>();

            var argentina = new Country
                                {
                                    Id = 1,
                                    Name = "Argentina"
                                };

            var uruguay = new Country
                              {
                                  Id = 2,
                                  Name = "Uruguay"
                              };
            
            var buenosAires = new City
                                  {
                                      Id = 1,
                                      Name = "Buenos Aires",
                                      Country = argentina
                                  };
            using (var s = memo.CreateSession())
            {
                s.Insert(uruguay);
                s.Insert(argentina);
                s.Insert(buenosAires);
                s.Flush();
            }
            
            buenosAires.Name = "bla";
            buenosAires.Country = uruguay;
            
            City buenosAires2;

            using (var s = memo.CreateSession())
            {
                buenosAires2 = s.GetById<City>(buenosAires.Id);
            }

            Assert.AreEqual("Buenos Aires", buenosAires2.Name);
            Assert.AreEqual("Argentina", buenosAires2.Country.Name);
        }

        [Test]
        public void InsertWithoutFlush()
        {
            var memo = new Memo()
                .Map<City>();

            var buenosAires = new City
            {
                Id = 1,
                Name = "Buenos Aires"
            };
            using (var s = memo.CreateSession())
            {
                s.Insert(buenosAires); //not flushed!
            }

            City buenosAires2;

            using (var s = memo.CreateSession())
            {
                buenosAires2 = s.GetById<City>(buenosAires.Id);
            }

            Assert.IsNull(buenosAires2);
        }

        [Test]
        public void IgnorePropertiesWithNoSetter()
        {
            var memo = new Memo()
                            .Map<ClassWithNoSetter>();

            var test = new ClassWithNoSetter
            {
                Id = 1,
                Property = "1234"
            };
            using (var s = memo.CreateSession())
            {
                s.Insert(test);
                s.Flush();
            }

            ClassWithNoSetter test2;

            using (var s = memo.CreateSession())
            {
                test2 = s.GetById<ClassWithNoSetter>(test.Id);
            }

            Assert.AreNotEqual(test, test2);
            Assert.AreEqual(test.NoSetter, test2.NoSetter);
        }

        private class ClassWithNoSetter
        {
            public int Id { get; set; }
            public string Property { get; set; }
            public string NoSetter { get { return "test"; } }
        }
    }
}
